#include <WProgram.h>
#include <Wire.h> // for I2C MotorDriver and Sensobar


#include "ROB_i2cBusMaster.h"


void Ci2cBusMaster::Begin(void) {
  Wire.begin();
  reset();
}


void Ci2cBusMaster::reset(void) {
  _locked = I2C_IDLE;
  _requestedAdr = 0;
  _requestedAckLen = 0;
}



uint8_t Ci2cBusMaster::available(void) {
  return (!_locked);
}


uint8_t Ci2cBusMaster::send(uint8_t adr, uint8_t len, uint8_t withAckLen, uint8_t * buffer) {

  if(_locked != I2C_IDLE)
    return I2C_ERROR_LOCKED;

  _requestedAckLen = withAckLen;
  _requestedAdr = adr;

  if(len) {	
    Wire.beginTransmission(adr);
    for(int i=0; i < len; i++)
      Wire.send(buffer[i]);
    Wire.endTransmission();
  }

  if(_requestedAckLen) {
    _locked = I2C_WAITING_FOR_ACK;
    Wire.requestFrom(_requestedAdr, _requestedAckLen);
  }

  return I2C_ERROR_NONE;
}


uint8_t Ci2cBusMaster::update(void) {

  if(_locked != I2C_WAITING_FOR_ACK) {
    return I2C_ERROR_NONE;
  }

  int l = Wire.available();
  if(l == _requestedAckLen) {

    for (int i=0; i < l; i ++)
      _rcvBuffer[i] = Wire.receive();

    _locked = I2C_ACK_RECEIVED;
    return I2C_ERROR_NONE;
  } 
  else {
    if(++_cycles >= I2C_TIMEOUT_CYCLES)
      return I2C_ERROR_TIMEOUT;
  }


}


uint8_t Ci2cBusMaster::ackReceived(uint8_t adr, uint8_t ackLen) {
  if(_locked != I2C_ACK_RECEIVED)
    return 0;

  if(adr == _requestedAdr && ackLen == _requestedAckLen)
    return 1;

  return 0;
}


uint8_t * Ci2cBusMaster::getAck(void) {
  reset();
  return _rcvBuffer;
}




Ci2cBusMaster I2cBusmaster;




